/**
 * Copy right 2013 by Phan Hoàn Vũ
 * Email hoanvuphan@gmail.com
 */
package vn.universex;

import japa.parser.JavaParser;
import japa.parser.ParseException;
import japa.parser.ast.CompilationUnit;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Set;

import org.codehaus.plexus.util.StringUtils;

import vn.universex.builder.ClassBuilderImpl;
import vn.universex.builder.ClassBuilderResult;

/**
 * TODO: javadoc please
 * 
 * @author Phan Hoan Vu
 * 
 */
public class PlainTextJavaClassGenerator {

    /**
     * The purpose of this method is to build the property class base on the source code of the given class.
     * 
     * @param sourceFile
     *            the source code file
     * @param outputDirectory
     *            the output directory of the generated class.
     * @param resultSuffix
     *            See --> {@link ClassBuilderImpl#resultSuffix}
     * @param packageInfos
     *            See --> {@link ClassBuilderImpl#packageInfos}
     */
    public final void generate(File sourceFile, File outputDirectory, String resultSuffix,
            Map<String, Set<String>> packageInfos) {
        try (InputStream is = new FileInputStream(sourceFile)) {
            CompilationUnit cu = JavaParser.parse(is);
            ClassBuilderResult result = new ClassBuilderImpl(resultSuffix, packageInfos).build(cu);

            String packageName = result.getPackageName();
            String className = result.getClassName();
            String classContent = result.getClassContent();

            serializeJavaClass(className, packageName, classContent, outputDirectory);

        } catch (IOException | ParseException e) {
            throw new RuntimeException("Eror when generate result", e);
        }
    }

    /**
     * @param className
     * @param packageName
     * @param classContent
     * @param outputDirectory
     * @throws IOException
     * @throws FileNotFoundException
     */
    public void serializeJavaClass(String className, String packageName, String classContent, File outputDirectory)
            throws IOException, FileNotFoundException {
        if (!outputDirectory.exists() && !outputDirectory.mkdirs()) {
            throw new IOException("Can not create output directory: " + outputDirectory.getAbsolutePath());
        }

        if (outputDirectory.isDirectory()) {

            String packagePath = StringUtils.replace(packageName, ".", File.separator);
            String pathname = outputDirectory.getAbsolutePath() + File.separatorChar + packagePath + File.separatorChar;

            File resultFile = new File(pathname + className + ".java");
            if (!resultFile.getParentFile().exists() && !resultFile.getParentFile().mkdirs()) {
                throw new IOException("Can not create output directory: "
                        + resultFile.getParentFile().getAbsolutePath());
            }
            try (PrintWriter printWriter = new PrintWriter(new FileOutputStream(resultFile))) {
                printWriter.write(classContent);
            }
        }
    }
}
